package com.quan.server.endpoint;

import com.mark.util.CommonUtil;
import com.mark.util.JsonUtil;
import com.mark.util.wxmp.WeixinMPClient;
import com.mark.util.wxmp.mpbeans.Message;
import com.quan.server.Config;
import com.quan.server.helper.MyAppHelper;
import org.apache.commons.betwixt.io.BeanReader;
import org.apache.commons.betwixt.io.BeanWriter;
import org.apache.commons.betwixt.strategy.CapitalizeNameMapper;
import org.apache.commons.betwixt.strategy.MixedContentEncodingStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.io.BufferedReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@Path("/message")
public class MessageEndpoint {
    private static Logger logger = LoggerFactory.getLogger(MessageEndpoint.class);
    public static final String MESSAGE_TEXT = "text";
    public static final String MESSAGE_IMAGE = "image";
    public static final String MESSAGE_VOICE = "voice";
    public static final String MESSAGE_VIDEO = "video";
    public static final String MESSAGE_LINK = "link";
    public static final String MESSAGE_LOCATION = "location";
    public static final String MESSAGE_EVENT = "event";
    public static final String MESSAGE_EVENT_SUBSCRIBE = "subscribe";
    public static final String MESSAGE_EVENT_UNSUBSCRIBE = "unsubscribe";
    public static final String MESSAGE_EVENT_CLICK = "CLICK";
    public static final String MESSAGE_EVENT_VIEW = "VIEW";

    @Autowired
    private Config config;

    @Autowired
    private MyAppHelper myAppHelper;

    @Context
    HttpServletRequest request;

    @Context
    HttpServletResponse response;

    @Context
    private UriInfo uriInfo;

    @GET
    public Response get(@QueryParam("timestamp") String timestamp,
                        @QueryParam("nonce") String nonce,
                        @QueryParam("signature") String signature,
                        @QueryParam("echostr") String echostr
    ) {
        try {
            String token = config.qunWeixinMPToken;
            logger.error("get times:{}, nonce:{}, signature:{}, echostr:{}, token:{}", timestamp, nonce, signature, echostr, token);
            boolean result = checkToken(timestamp, nonce, token, signature);
            logger.error("message result=" + result);
            if (result) {
                return Response.ok(echostr).build();
            } else {
                return Response.ok().build();
            }
        } catch (Exception e) {
            logger.error("", e);
            return Response.ok().build();
        }
    }

    public static boolean checkToken(String timestamp, String nonce, String token, String signature) {
        if (timestamp != null && nonce != null && token != null && signature != null) {
            String[] array = new String[]{timestamp, nonce, token};
            Arrays.sort(array);
            String value = "";
            for (String string : array) {
                value = value + string;
            }
            String sha1 = CommonUtil.encodeSha1(value);
            boolean result = sha1.equals(signature);
            return result;
        }
        return false;
    }

    @POST
    public Response post(String xml) {
        try {
            request.setCharacterEncoding("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        response.setCharacterEncoding("UTF-8");
        try {
            logger.error("weixinmp message xml=" + xml);
            Message message = convertXML2Message(xml);
            String fromUserName = message.getFromUserName();//发送者的微信公众号OpenId
            String toUserName = message.getToUserName();//公众号的微信号
            String content = message.getContent();
            String messageType = message.getMsgType();
            String event = message.getEvent();
            Message outputMessage = new Message();
            if (MESSAGE_TEXT.equals(messageType)) {
                if (myAppHelper.isYouhuiquanMessage(content)) {
                    logger.error("-----------> 1");
                    String weixinSenderOpenId = fromUserName;
                    content = myAppHelper.handleMessageByOpenId(weixinSenderOpenId, content);
                    outputMessage = createTextMessage(toUserName, fromUserName, content, MESSAGE_TEXT);
                } else if ("1".equals(content.trim())) {
                    content = getMenuText();
                    outputMessage = createTextMessage(toUserName, fromUserName, content, MESSAGE_TEXT);
                } else if ("2".equals(content.trim())) {
                    content = "有什么问题？";
                    outputMessage = createTextMessage(toUserName, fromUserName, content, MESSAGE_TEXT);
                } else if ("?".equals(content.trim()) || "？".equals(content.trim())) {
                    content = getMenuText();
                    outputMessage = createTextMessage(toUserName, fromUserName, content, MESSAGE_TEXT);
                } else {
                    content = "有问题，可以联系客服MM， 不识别 " + content;
                    outputMessage = createTextMessage(toUserName, fromUserName, content, MESSAGE_TEXT);
                }
            } else if (MESSAGE_EVENT.equals(message.getMsgType())) {
                if (MESSAGE_EVENT_SUBSCRIBE.equals(event)) {
                    content = welcomeMessage() + "\n" +
                        getMenuText();
                    outputMessage = createTextMessage(toUserName, fromUserName, content, MESSAGE_TEXT);
                }
                if (MESSAGE_EVENT_UNSUBSCRIBE.equals(event)) {
                    outputMessage = createTextMessage(toUserName, fromUserName, content, MESSAGE_TEXT);
                }
                if (MESSAGE_EVENT_CLICK.equals(event)) {
                }
                if (MESSAGE_EVENT_VIEW.equals(event)) {
                }
            }
            logger.error("output message:" + JsonUtil.bean2Json(outputMessage));
            String outputXml = convertMessage2XML(outputMessage);
            Response response = Response.ok(outputXml).build();
            return response;
        } catch (Exception e) {
            logger.error("", e);
            Response response = Response.ok().build();
            return response;
        }
    }

    @PUT
    public Response put(Object o) {
        logger.error("message=" + "put");
        Response response = Response.ok().build();
        return response;
    }

    @DELETE
    public Response delete(Object o) {
        logger.error("message=" + "delete");
        Response response = Response.ok().build();
        return response;
    }

    @GET
    @Path("/templateMessage")
    public Response sendTemplateMessage(@QueryParam("openId") String openId,
                                        @QueryParam("url") String url,
                                        @QueryParam("message") String message,
                                        @QueryParam("doctorCatalog") String doctorCatalog,
                                        @QueryParam("doctorName") String doctorName,
                                        @QueryParam("remark") String remark
    ) {
        String accessToken = config.getAccessToken();
        String templateId = "YkNpPx-oSIdXlXgisbBifhUBQi_uOz46RzbsdOtaJSM";
//        {{first.DATA}}
//
//        科室: {{deptname.DATA}}
//        医生: {{doctorname.DATA}}
//        {{remark.DATA}}
        Map<String, Map<String, String>> data = new HashMap<>();
        setData(data, "first", message);
        setData(data, "deptname", doctorCatalog);
        setData(data, "doctorname", doctorName);
        setData(data, "remark", remark);
        boolean result = WeixinMPClient.sendMessage(accessToken, openId, templateId, url, data);
        if (result) {
            return Response.ok().build();
        } else {
            return Response.serverError().build();
        }
    }

    public static Map<String, Map<String, String>> setData(Map<String, Map<String, String>> data, String
        key, String value) {
        return setData(data, key, value, "#173177");
    }

    public static Map<String, Map<String, String>> setData(Map<String, Map<String, String>> data, String
        key, String value, String color) {
        Map<String, String> valueMap = new HashMap<>();
        valueMap.put("value", value);
        valueMap.put("color", color);
        data.put(key, valueMap);
        return data;
    }

    public static String getMenuText() {
        String menu = "";
        menu = menu + "1 牛起盟介绍\n";
        menu = menu + "2 功能介绍\n";
        menu = menu + "回复 ？调出此菜单\n";
        return menu;
    }

    public static String welcomeMessage() {
        return "欢迎使用可以 '躺着赚钱，开心购物'的'圈'。";
    }

    public static Message createTextMessage(String fromUserName, String toUserName, String content, String
        messageType) {
        Message message = new Message();
        message.setMsgType(messageType);
        message.setFromUserName(fromUserName);
        message.setToUserName(toUserName);
        message.setContent(content);
        message.setCreateTime(String.valueOf(new Date().getTime()));
        message.setContent(content);
        return message;
    }
//    public static void main(String[] args) {
//        System.out.println(getMenuText());
//    }

    public static Message convertXML2Message(String xmlString) {
        try {
            StringReader xmlReader = new StringReader(xmlString);
            BeanReader beanReader = new BeanReader();
            beanReader.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false);
            beanReader.getXMLIntrospector().getConfiguration().setElementNameMapper(new CapitalizeNameMapper());//节点大写
            beanReader.getBindingConfiguration().setMapIDs(false);
            beanReader.registerBeanClass("xml", Message.class);
            Message message = (Message) beanReader.parse(xmlReader);
            return message;
        } catch (Exception e) {
            logger.error("", e);
            return null;
        }
    }

    public static String convertMessage2XML(Object object) {
        String xml = "";
        try {
            StringWriter outputWriter = new StringWriter();
            BeanWriter beanWriter = new BeanWriter(outputWriter);
            beanWriter.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false);
            beanWriter.getXMLIntrospector().getConfiguration().setElementNameMapper(new CapitalizeNameMapper());//节点大写
            beanWriter.setMixedContentEncodingStrategy(MixedContentEncodingStrategy.CDATA);//CDATA
            beanWriter.getBindingConfiguration().setMapIDs(false);
            beanWriter.enablePrettyPrint();
            beanWriter.write("xml", object);
            xml = outputWriter.toString();
            outputWriter.close();
        } catch (Exception e) {
            logger.error("", e);
        }
        return xml;
    }
}